package com.chenyu.upload.util;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.concurrent.Callable;

/**
 * http工具类
 *
 * @author yu_chen
 * @date 2018年4月23日12:12:35
 */
@Slf4j
public class HttpUtils {


    /**
     * 向指定URL发送GET方法的请求
     *
     * @param path   发送请求的 URL
     * @param params 请求参数，请求参数应该是 name1=value1&name2=value2 的形式。
     * @return URL 所代表远程资源的响应结果
     */
    public static String sendGet(String path, String params) {
        if (StringUtils.isNotEmpty(params)) {
            path += "?" + params;
        }
        try {
            URL url = new URL(path);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setConnectTimeout(5 * 1000);
            conn.setRequestMethod("GET");
            InputStream inStream = conn.getInputStream();
            byte[] data = StreamTool.readInputStream(inStream);
            return new String(data, "UTF-8");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    /**
     * 向指定 URL 发送POST方法的请求
     *
     * @param path   发送请求的 URL
     * @param params 请求参数，请求参数应该是 name1=value1&name2=value2 的形式。
     * @return 所代表远程资源的响应结果
     */
    public static String sendPost(String path, String params) {
        try {
            return sendPostNotTryCatch(path, params);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    /**
     * 发送post请求不捕获异常
     *
     * @param path   请求路径
     * @param params 请求参数
     * @return 0 byte
     * @throws Exception
     */
    public static byte[] sendPostReturnByteNotTryCatch(String path, String params) throws Exception {
        URL url = new URL(path);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        // 提交模式
        conn.setRequestMethod("POST");
        //连接超时 单位毫秒
        conn.setConnectTimeout(5000);
        // 是否输入参数
        conn.setDoOutput(true);
        byte[] bypes = params.getBytes("UTF-8");
        // 输入参数
        conn.getOutputStream().write(bypes);
        InputStream inStream = conn.getInputStream();
        return StreamTool.readInputStream(inStream);
    }

    /**
     * 发送post请求不捕获异常
     *
     * @param path   请求路径
     * @param params 请求参数
     * @return 0
     * @throws Exception
     */
    public static String sendPostNotTryCatch(String path, String params) throws Exception {
        byte[] bytes = sendPostReturnByteNotTryCatch(path, params);
        return new String(bytes, "UTF-8");
    }

    /**
     * 异步发送post请求 并且具有失败重试功能
     *
     * @param path   请求路径
     * @param params 请求参数
     * @return string
     */
    public static String asynSendPost(String path, String params) {

        return asynSendPost(3, path, params);
    }

    /**
     * 调用一次post请求
     *
     * @param path
     * @param params
     * @return
     */
    private static String asynSendPost(int retryTimes, String path, String params) {
        String result = "";
        boolean isException = false;
        try {
            Callable<String> callable = () -> sendPostNotTryCatch(path, params);
            result = callable.call();
        } catch (Exception e) {
            isException = true;
            log.error(String.format("\n请求path：%s\n请求param：%s\n请求失败次数%s\n异常信息：%s", path, params, 4 - retryTimes, e.toString()));
        }
        if (isException && retryTimes > 0) {
            return asynSendPost(--retryTimes, path, params);
        }
        return result;
    }

}
